home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / Tools / Musik / Misc / Amster / Source / navigator.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-27  |  13.7 KB  |  450 lines

  1. /*
  2. ** Amster - Navigator
  3. ** by Jacob Laursen <laursen@myself.com>
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #include <proto/dos.h>
  11. #include <proto/socket.h>
  12. #include <proto/utility.h>
  13.  
  14. #include <netdb.h>
  15. #include <sys/time.h>
  16. #include <sys/socket.h>
  17. #include <sys/ioctl.h>
  18. #include <netinet/tcp.h>
  19. #include <bsdsocket/socketbasetags.h>
  20. #include <error.h>
  21. #include <time.h>
  22.  
  23. #include <MUI/NListview_mcc.h>
  24.  
  25. #include "include/config.h"
  26. #include "include/gui.h"
  27. #include "include/info.h"
  28. #include "include/mui.h"
  29. #include "include/navigator.h"
  30. #include "include/prefs.h"
  31.  
  32. #include "include/protos.h"
  33. #include "amster_Cat.h"
  34.  
  35. /* Global variables */
  36.  
  37. BOOL ServerListChanged = FALSE;
  38.  
  39. /* Private prototypes */
  40.  
  41. void LoadServerList(struct NavigatorData *data);
  42. void SaveServerList(struct NavigatorData *data);
  43. void MarkServerOnline(struct NavigatorData *data, char *server);
  44. MUIF ServerListDisplay(REG(a2) char **array, REG(a1) struct ServerEntry *entry);
  45. MUIF ServerListCompare(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm);
  46. MUIF ServerListDestruct(REG(a2) APTR pool, REG(a1) struct ServerEntry *entry);
  47. MUIF ServerString(REG(a0) struct Hook *hook, REG(a1) APTR *contents);
  48.  
  49.  
  50. MUIF NavigatorDispatch(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
  51. {
  52.     struct NavigatorData *data;
  53.     struct ServerEntry *entry;
  54.     char *buf;
  55.  
  56.     switch (msg->MethodID) {
  57.         case OM_NEW:
  58.             return(NavigatorNew(cl, obj, (APTR)msg));
  59.         case NAVI_CONNECT:
  60.             data = INST_DATA(cl, obj);
  61.             if (gui_napon) nap_logout();
  62.             get(data->ST_Server, MUIA_String_Contents, &buf);
  63.             if (!gui_napon) {
  64.                 nap_login_fromlist(buf);
  65.             }
  66.             return(NULL);
  67.         case NAVI_GETSERVER:
  68.             data = INST_DATA(cl, obj);
  69.             DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
  70.             if (entry) {
  71.                 set(data->ST_Server,  MUIA_String_Contents, entry->Name);
  72.                 set(data->ST_Comment, MUIA_String_Contents, entry->Comment);
  73.             }
  74.             return(NULL);
  75.         case NAVI_ADDSERVER:
  76.             {
  77.             BOOL selected = FALSE;
  78.  
  79.             data = INST_DATA(cl, obj);
  80.             DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
  81.             if (entry) selected = TRUE;    /* One entry is already selected */
  82.  
  83.             if (entry = malloc(sizeof(struct ServerEntry))) {
  84.                 entry->LastOnline = 0;
  85.                 if (selected) {
  86.                     /* We clear the fields instead of dublicating selected entry */
  87.                     entry->Name = strdup(MSG_NAVIGATOR_NEW);
  88.                     entry->Comment = strdup("");
  89.                 }
  90.                 else {
  91.                     get(data->ST_Server, MUIA_String_Contents, &buf);
  92.                     entry->Name = strdup(buf);
  93.                     get(data->ST_Comment, MUIA_String_Contents, &buf);
  94.                     entry->Comment = strdup(buf);
  95.                 }
  96.                 DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
  97. /*                DoMethod(data->LV_Server, MUIM_NList_Jump, MUIV_NList_Jump_Active);*/
  98.                 ServerListChanged = TRUE;
  99.             }
  100.             }
  101.             return(NULL);
  102.         case NAVI_REMOVESERVER:
  103.             data = INST_DATA(cl, obj);
  104.             DoMethod(data->LV_Server, MUIM_NList_Remove, MUIV_NList_Remove_Active);
  105.             ServerListChanged = TRUE;
  106.             return(NULL);
  107.         case NAVI_REDRAWSERVER:
  108.             {
  109.             struct ServerEntry *entry;
  110.             APTR *contents = (APTR)(((muimsg)msg)->arg1);
  111.             data = INST_DATA(cl, obj);
  112.  
  113.             DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
  114.             if (entry) {
  115.                 if (*(contents+1) == 0) entry->Name = strdup(*contents);
  116.                 else entry->Comment = strdup(*contents);
  117.                 DoMethod(data->LV_Server, MUIM_NList_Redraw, MUIV_NList_Redraw_Active);
  118.                 ServerListChanged = TRUE;
  119.             }
  120.             return(NULL);
  121.             }
  122.         case NAVI_LOAD:
  123.             data = INST_DATA(cl, obj);
  124.             LoadServerList(data);
  125.             return(NULL);
  126.         case NAVI_SAVE:
  127.             data = INST_DATA(cl, obj);
  128.             SaveServerList(data);
  129.             return(NULL);
  130.         case NAVI_MARKSERVER:
  131.             data = INST_DATA(cl, obj);
  132.             MarkServerOnline(data, (char *)(((muimsg)msg)->arg1));
  133.             return(NULL);
  134.     }
  135.     return(DoSuperMethodA(cl, obj, msg));
  136. }
  137.  
  138.  
  139. ULONG NavigatorNew(struct IClass *cl, Object *obj, struct opSet *msg)
  140. {
  141.     static const struct Hook ServerListDispHook = { {NULL, NULL}, &ServerListDisplay,  NULL, NULL };
  142.     static const struct Hook ServerListCompHook = { {NULL, NULL}, &ServerListCompare,  NULL, NULL };
  143.     static const struct Hook ServerListDestHook = { {NULL, NULL}, &ServerListDestruct, NULL, NULL };
  144.     static const struct Hook ServerStringHook   = { {NULL, NULL}, &ServerString,       NULL, NULL };
  145.  
  146.     struct NavigatorData *data;
  147.  
  148.     Object *LV_Server, *ST_Server, *ST_Comment;
  149.     Object *BT_ConnectConnect, *BT_ConnectAdd, *BT_ConnectRemove;
  150.  
  151.     if (obj = (Object *)DoSuperNew(cl, obj,
  152.         MUIA_HelpNode, "navi",
  153.         MUIA_Window_Title, MSG_NAVIGATOR_TITLE,
  154.         MUIA_Window_ID, MAKE_ID('N','A','V','I'),
  155.         WindowContents, VGroup,
  156.             Child, LV_Server = NListviewObject,
  157.                 MUIA_NList_Input, TRUE,
  158.                 MUIA_NListview_NList, NListObject,
  159.                     InputListFrame,
  160.                     MUIA_NList_ListBackground, MUII_ListBack,
  161.                     MUIA_NList_TitleBackground, MUII_ListBack,
  162.                     MUIA_NList_Title, TRUE,
  163.                     MUIA_NList_Format, "BAR,BAR,BAR",
  164.                     MUIA_NList_DisplayHook, &ServerListDispHook,
  165.                     MUIA_NList_CompareHook2, &ServerListCompHook,
  166.                     MUIA_NList_DestructHook, &ServerListDestHook,
  167.                 End,
  168.             End,
  169.             Child, ColGroup(2),
  170.                 Child, Label2(MSG_NAVIGATOR_SERVER),
  171.                 Child, ST_Server = StringObject,
  172.                     MUIA_HorizWeight, 400,
  173.                     StringFrame,
  174.                 End,
  175.                 Child, Label2(MSG_NAVIGATOR_COMMENT),
  176.                 Child, ST_Comment = StringObject,
  177.                     MUIA_HorizWeight, 400,
  178.                     StringFrame,
  179.                 End,
  180.             End,
  181.             Child, RectangleObject,
  182.                 MUIA_FixHeight, 8,
  183.                 MUIA_Rectangle_HBar, TRUE,
  184.             End,
  185.             Child, HGroup,
  186.                 Child, BT_ConnectConnect = SimpleButton(MSG_NAVIGATOR_CONNECT_GAD),
  187.                 Child, BT_ConnectRemove  = SimpleButton(MSG_NAVIGATOR_REMOVE_GAD),
  188.                 Child, BT_ConnectAdd     = SimpleButton(MSG_NAVIGATOR_ADD_GAD),
  189. /*
  190.                 Child, HGroup,
  191.                     Child, BT_Update     = SimpleButton(MSG_NAVIGATOR_UPDATE_GAD),
  192.                         MUIA_ShortHelp, MSG_NAVIGATOR_UPDATE_HELP,
  193.                 End,
  194. */
  195.             End,
  196.         End,
  197.         TAG_MORE, msg->ops_AttrList))
  198.     {
  199.         data = INST_DATA(cl, obj);
  200.         data->LV_Server  = LV_Server;
  201.         data->ST_Server  = ST_Server;
  202.         data->ST_Comment = ST_Comment;
  203.  
  204.         DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, obj, 3, MUIM_Set, MUIA_Window_Open, FALSE);
  205.  
  206.         DoMethod(LV_Server, MUIM_Notify, MUIA_NList_TitleClick,  MUIV_EveryTime, LV_Server, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);
  207.         DoMethod(LV_Server, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, LV_Server, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2);
  208.         DoMethod(LV_Server, MUIM_Notify, MUIA_NList_SortType,    MUIV_EveryTime, LV_Server, 3, MUIM_Set, MUIA_NList_TitleMark,  MUIV_TriggerValue);
  209.         DoMethod(LV_Server, MUIM_Notify, MUIA_NList_SortType2,   MUIV_EveryTime, LV_Server, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue);
  210. /*        DoMethod(LV_Server, MUIM_NList_Sort3, 1, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);*/
  211.  
  212.         DoMethod(BT_ConnectConnect, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_CONNECT);
  213.         DoMethod(BT_ConnectRemove,  MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_REMOVESERVER);
  214.         DoMethod(BT_ConnectAdd,     MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_ADDSERVER);
  215. /*        DoMethod(BT_Update,         MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_GETNAPIGATOR);*/
  216.         DoMethod(LV_Server, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, NAVI_CONNECT);
  217.  
  218.         LoadServerList(data);
  219.  
  220.         DoMethod(LV_Server, MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, obj, 1, NAVI_GETSERVER);
  221.  
  222.         set(ST_Server, MUIA_String_AttachedList, LV_Server);
  223.  
  224.         DoMethod(ST_Server,  MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, ST_Server, 4, MUIM_CallHook, &ServerStringHook, MUIV_TriggerValue, 0);
  225.         DoMethod(ST_Comment, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, ST_Server, 4, MUIM_CallHook, &ServerStringHook, MUIV_TriggerValue, 1);
  226.  
  227.         return((ULONG)obj);
  228.     }
  229.     return(0);
  230. }
  231.  
  232.  
  233. void LoadServerList(struct NavigatorData *data)
  234. {
  235.     BPTR fh;
  236.     char buf[1024];
  237.     int line = 0;
  238.     struct ServerEntry *entry;
  239.     LONG argarray[] = { NULL, NULL, NULL };
  240.     UBYTE *argstr = "HOST/A,LASTUSED/A/N,COMMENT/K";
  241.     struct RDArgs *rdargs;
  242.  
  243.     if (fh = Open("PROGDIR:Amster.servers", MODE_OLDFILE)) {
  244.         while (FGets(fh, buf, sizeof(buf))) {
  245.             line++;
  246.             if (rdargs = AllocDosObject(DOS_RDARGS, NULL)) {
  247.                 rdargs->RDA_Buffer = NULL;
  248.                 rdargs->RDA_Source.CS_Buffer = buf;
  249.                 rdargs->RDA_Source.CS_Length = strlen(buf);
  250.                 argarray[2] = 0;
  251.                 if (ReadArgs(argstr, argarray, rdargs)) {
  252.                     if (entry = malloc(sizeof(struct ServerEntry))) {
  253.                         entry->Name = strdup((char *)argarray[0]);
  254.                         entry->LastOnline = *((long *)argarray[1]);
  255.                         if (argarray[2]) entry->Comment = strdup((char *)argarray[2]);
  256.                         else entry->Comment = strdup("");
  257.                         entry->Ping = -1;
  258.                         DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
  259.                     }
  260.                 }
  261.                 else gui_debugf("Error parsing '%s' line #%ld\n", "PROGDIR:Amster.servers", line);
  262.                 FreeDosObject(DOS_RDARGS, rdargs);
  263.             }
  264.         }
  265.         Close(fh);
  266.         DoMethod(data->LV_Server, MUIM_NList_Sort);
  267.     }
  268. }
  269.  
  270.  
  271. void SaveServerList(struct NavigatorData *data)
  272. {
  273.     struct ServerEntry *entry;
  274.     BPTR fh;
  275.     char buf[1024];
  276.     int i;
  277.  
  278.     fh = Open("PROGDIR:Amster.servers", MODE_NEWFILE);
  279.     if (!fh) return;
  280.  
  281.     for (i=0; ; i++) {
  282.         DoMethod(data->LV_Server, MUIM_NList_GetEntry, i, &entry);
  283.         if (!entry) break;
  284.         if (entry->Comment) {
  285.             if (entry->Comment[0] != '\0')
  286.                 sprintf(buf, "%s %ld COMMENT \"%s\"\n", entry->Name, entry->LastOnline, entry->Comment);
  287.             else sprintf(buf, "%s %ld\n", entry->Name, entry->LastOnline);
  288.         }
  289.         else sprintf(buf, "%s %ld\n", entry->Name, entry->LastOnline);
  290.         Write(fh, buf, strlen(buf)); /* Should be buffered, check FWrite */
  291.     }
  292.  
  293.     Close(fh);
  294.     ServerListChanged = FALSE;
  295. }
  296.  
  297.  
  298. void MarkServerOnline(struct NavigatorData *data, char *server)
  299. {
  300.     struct ServerEntry *entry=0;
  301.     struct DateStamp *ds, *rds;
  302.     int i;
  303.     BOOL new = FALSE;
  304.  
  305.     for (i=0; ; i++) {
  306.         DoMethod(data->LV_Server, MUIM_NList_GetEntry, i, &entry);
  307.         if (!entry) break;
  308.         if (strcmp(server, entry->Name) == 0) break;
  309.     }
  310.     if (!entry) {    /* Server not already on list */
  311.         if (prf->ServerList < 2) return;
  312.         if (entry = malloc(sizeof(struct ServerEntry))) {
  313.             entry->Name = strdup(server);
  314.             entry->LastOnline = 0;    /* In case we don't succeed later on... */
  315.             entry->Comment = strdup("");
  316.             entry->Ping = -1;
  317.             new = TRUE;
  318.         }
  319.     }
  320.  
  321.     if (ds = malloc(sizeof(struct DateStamp))) {
  322.         memset(ds, 0, sizeof(struct DateStamp));
  323.         if (rds = DateStamp(ds)) {
  324.             entry->LastOnline = rds->ds_Days*24*60*60 + rds->ds_Minute*60 + rds->ds_Tick/50;
  325.             if (new)
  326.                 DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
  327.             else
  328.                 DoMethod(data->LV_Server, MUIM_NList_Redraw, i);
  329.             ServerListChanged = TRUE;
  330.         }
  331.         free(ds);
  332.     }
  333. }
  334.  
  335.  
  336. MUIF ServerListDisplay(REG(a2) char **array, REG(a1) struct ServerEntry *entry)
  337. {
  338.     struct ClockData *cd;
  339.     static char buf[20], buf2[20];
  340.  
  341.     if (entry) {
  342.         *array++ = entry->Name;
  343.         if (entry->LastOnline == 0) *array++ = "-";
  344.         else {
  345.             if (cd = malloc(sizeof(struct ClockData))) {
  346.                 Amiga2Date(entry->LastOnline, cd);
  347.                 sprintf(buf, "%02d/%02d/%d %02d:%02d:%02d", cd->month, cd->mday, cd->year, cd->hour, cd->min, cd->sec);
  348.                 *array++ = buf;
  349.                 free(cd);
  350.             }
  351.             else *array++ = "-";
  352.         }
  353.         *array++ = entry->Comment;
  354.  
  355.         if (entry->Ping >= 0) {
  356.             sprintf(buf2, "%ld", entry->Ping);
  357.             *array   = buf2;
  358.         }
  359.         else *array = "-";
  360.     }
  361.     else {
  362.         *array++ = (char *)MSG_NAVIGATOR_LIST_SERVER;
  363.         *array++ = (char *)MSG_NAVIGATOR_LIST_LASTONLINE;
  364.         *array++ = (char *)MSG_NAVIGATOR_LIST_COMMENT;
  365.         *array   = (char *)MSG_NAVIGATOR_LIST_PING;
  366.     }
  367.  
  368.     return 0;
  369. }
  370.  
  371.  
  372. MUIF ServerListCompare(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm)
  373. {
  374.     struct ServerEntry *entry1 = ncm->entry1;
  375.     struct ServerEntry *entry2 = ncm->entry2;
  376.     LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask;
  377.     LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask;
  378.     ULONG result = 0;
  379.  
  380.     if (ncm->sort_type == MUIV_NList_SortType_None) return (0);
  381.  
  382.     if (col1 == 0) {
  383.         if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
  384.             result = (LONG) stricmp(entry2->Name, entry1->Name);
  385.         else
  386.             result = (LONG) stricmp(entry1->Name, entry2->Name);
  387.     }
  388.     else if (col1 == 1) {
  389.         if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
  390.             result = entry2->LastOnline - entry1->LastOnline;
  391.         else
  392.             result = entry1->LastOnline - entry2->LastOnline;
  393.     }
  394.     else if (col1 == 2) {
  395.         if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
  396.             result = (LONG) stricmp(entry2->Comment, entry1->Comment);
  397.         else
  398.             result = (LONG) stricmp(entry1->Comment, entry2->Comment);
  399.     }
  400.     else if (col1 == 3) {
  401.         if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
  402.             result = entry2->Ping - entry1->Ping;
  403.         else
  404.             result = entry1->Ping - entry2->Ping;
  405.     }
  406.  
  407.     if ((result != 0) || (col1 == col2)) return (result);
  408.  
  409.     if (col2 == 0) {
  410.         if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
  411.             result = (LONG) stricmp(entry2->Name, entry1->Name);
  412.         else
  413.             result = (LONG) stricmp(entry1->Name, entry2->Name);
  414.     }
  415.     else if (col2 == 1) {
  416.         if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
  417.             result = entry2->LastOnline - entry1->LastOnline;
  418.         else
  419.             result = entry1->LastOnline - entry2->LastOnline;
  420.     }
  421.     else if (col2 == 2) {
  422.         if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
  423.             result = (LONG) stricmp(entry2->Comment, entry1->Comment);
  424.         else
  425.             result = (LONG) stricmp(entry1->Comment, entry2->Comment);
  426.     }
  427.     else if (col2 == 3) {
  428.         if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
  429.             result = entry2->Ping - entry1->Ping;
  430.         else
  431.             result = entry1->Ping - entry2->Ping;
  432.     }
  433.  
  434.     return (result);
  435. }
  436.  
  437.  
  438. MUIF ServerListDestruct(REG(a2) APTR pool, REG(a1) struct ServerEntry *entry)
  439. {
  440.     free(entry);
  441.     return(0);
  442. }
  443.  
  444.  
  445. MUIF ServerString(REG(a0) struct Hook *hook, REG(a1) APTR *contents)
  446. {
  447.     DoMethod(gui->WI_Navigator, NAVI_REDRAWSERVER, contents);
  448.     return(0);
  449. }
  450.